﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Windows.Forms;

namespace AutoUI
{
    /// <summary>
    /// 控件工具类
    /// </summary>
    public static class CtrolTools
    {
        #region 设置字体图标

        /// <summary>
        /// 设置字体图标
        /// </summary>
        /// <param name="ctr"></param>
        /// <param name="FontIcon">字体图标文件的名称，若不是跟目录下，需要加上对应的路径，比如 Fonts\iconfont.ttf</param>
        public static void AddFontIcon(this Control ctr, string FontIconPath = "iconfont.ttf")
        {
            var font = ctr.Font.Size;
            pfcc = new System.Drawing.Text.PrivateFontCollection();
            var path = Environment.CurrentDirectory + "\\" + FontIconPath;
            pfcc.AddFontFile(path);
            ctr.Font = new Font(pfcc.Families[0], font);
        }

        private static System.Drawing.Text.PrivateFontCollection pfcc;

        #endregion 设置字体图标

        #region 容器控件支持自动缩放

        private static Dictionary<Control, CtrolInfo> DicSizeTemp = new Dictionary<Control, CtrolInfo>();

        /// <summary>
        /// 控件支持自动缩放 （需要优化为容器控件开可以）
        /// </summary>
        /// <param name="ctr"></param>
        /// <param name="onlySelf">是否只缩放自己,不缩放子控件，默认缩放所有</param>
        /// <param name="MouseWheel">鼠标中键控制缩放？默认为true，可以控制</param>
        public static void AddAutoScale(this Control ctr, bool onlySelf = false, bool MouseWheel = true)
        {
            var form = ctr.FindForm();
            form.FormClosed += Form_FormClosed1;
            SetDoubleBuffered(ctr);
            if (MouseWheel)
            {
                ctr.MouseWheel += Ctr_MouseWheel;
            }
            if (!DicSizeTemp.ContainsKey(ctr))
            {
                DicSizeTemp.Add(ctr, new CtrolInfo() { Rectangle = ctr.Bounds, Font = ctr.Font });
            }
            if (!onlySelf)
            {
                RecordOriginalSize(ctr);
                ctr.SizeChanged += SizeChange;
            }
            else
            {
            }
        }

        private static void Form_FormClosed1(object sender, FormClosedEventArgs e)
        {
            Remove((Control)sender);
        }

        private static void Remove(Control ctr)
        {
            if (DicSizeTemp.ContainsKey(ctr))
            {
                DicSizeTemp.Remove(ctr);
                if (ctr.HasChildren)
                {
                    foreach (Control item in ctr.Controls)
                    {
                        Remove(item);
                    }
                }
            }
        }

        private static void Ctr_MouseWheel(object sender, MouseEventArgs e)
        {
            try
            {
                //滚轮改变大小
                var direction = e.Delta > 0 ? true : false;//方向
                var ctrol = (Control)sender;
                var xdelta = 0.1 * ctrol.Width;//x轴增加的量
                var ydelta = 0.1 * ctrol.Height;//Y轴增加的量
                var xscale = (float)e.X / ctrol.Width;
                var yscale = (float)e.Y / ctrol.Height;
                var xoffset = xdelta * xscale;
                var yoffset = ydelta * yscale;
                ctrol.Width = ctrol.Width + (direction ? (int)xdelta : -(int)xdelta);
                ctrol.Height = ctrol.Height + (direction ? (int)ydelta : -(int)ydelta);
                var X = ctrol.Location.X + (direction ? -(int)xoffset : (int)xoffset);
                var Y = ctrol.Location.Y + (direction ? -(int)yoffset : (int)yoffset);
                ctrol.Location = new Point(X, Y);
                // var position = Control.MousePosition;

                Console.WriteLine($"{X}:{Y}");
                Console.WriteLine($"{ctrol.Width}:{ctrol.Height}");
            }
            catch (Exception ex)
            {
                MessageBox.Show("Test");
            }
        }

        /// <summary>
        /// 遍历记录子控件的位置及字体大小:
        /// </summary>
        /// <param name="ctr"></param>
        private static void RecordOriginalSize(Control ctr)
        {
            foreach (Control con in ctr.Controls)
            {
                if (!DicSizeTemp.ContainsKey(con))
                {
                    DicSizeTemp.Add(con, new CtrolInfo() { Rectangle = con.Bounds, Font = con.Font });
                }
                //  con.AccessibleDescription = con.Width + ";" + con.Height + ";" + con.Left + ";" + con.Top + ";" + con.Font.Size;
                if (con.Controls.Count > 0)
                {
                    RecordOriginalSize(con);
                }
            }
        }

        private static void SizeChange(object sender, EventArgs e)
        {
            var ctr = sender as Control;
            //    string[] mytag = ctr.AccessibleDefaultActionDescription.ToString().Split(new char[] { ';' });
            //float newx = (ctr.Width) / Convert.ToSingle(mytag[0]);
            //float newy = (ctr.Height) / Convert.ToSingle(mytag[1]);
            //计算缩放系数
            float newx = (ctr.Width) / (float)DicSizeTemp[ctr].Rectangle.Width;
            float newy = (ctr.Height) / (float)DicSizeTemp[ctr].Rectangle.Height;

            重新设置控件的大小位置和字体(newx, newy, ctr);
            //ctr.Tag = ctr.Size;
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="newx"></param>
        /// <param name="newy"></param>
        /// <param name="ctr"></param>
        private static void 重新设置控件的大小位置和字体(float newx, float newy, Control ctr)
        {
            //遍历窗体中的控件，重新设置控件的值
            foreach (Control con in ctr.Controls)
            {
                SetDoubleBuffered(con);
                con.Width = Convert.ToInt32(DicSizeTemp[con].Rectangle.Width * newx);//宽度
                con.Height = Convert.ToInt32(DicSizeTemp[con].Rectangle.Height * newy);//高度
                con.Left = Convert.ToInt32(DicSizeTemp[con].Rectangle.Left * newx);//左边距
                con.Top = Convert.ToInt32(DicSizeTemp[con].Rectangle.Top * newy);//顶边距
                                                                                 //Single currentSize = Convert.ToSingle(mytag[4]) * newy;//字体大小
                var newfontsize = Math.Min(newx, newy);
                if (newfontsize > 1)
                {
                    newfontsize = (float)Math.Floor(newfontsize);
                }
                // if (newfontsize > 0)
                //{
                Single currentSize = Convert.ToSingle(DicSizeTemp[con].Font.Size) * newfontsize;//字体大小

                con.Font = new Font(con.Font.Name, currentSize<=0?1: currentSize, con.Font.Style, con.Font.Unit);
                //  }

                if (con.Controls.Count > 0)
                {
                    重新设置控件的大小位置和字体(newx, newy, con);
                }
                //}
            }
        }

        #endregion 容器控件支持自动缩放

        #region 支持拖动

        private static Dictionary<Control, Point> MoveForms = new Dictionary<Control, Point>();

        /// <summary>
        /// 为控件增加移动所在窗体的功能
        /// </summary>
        /// <param name="ctr"></param>
        public static void AddMove(this Control ctr)
        {
            var form = ctr.FindForm();
            form.FormClosed += Form_FormClosed;
            ctr.MouseDown += Form_MouseDown1;
            ctr.MouseMove += Form_MouseMove1;
        }

        private static void Form_FormClosed(object sender, FormClosedEventArgs e)
        {
            MoveForms.Remove((Form)sender);
        }

        private static void Form_MouseMove1(object sender, MouseEventArgs e)
        {
            var form = ((Control)sender).FindForm();
            var form2 = ((Control)sender);
            if (e.Button == MouseButtons.Left)
            {
                //控制父级窗体移动
               // form2.Left += e.Location.X - MoveForms[form].X;
               // form2.Top += e.Location.Y - MoveForms[form].Y;
                //控制自己移动
                form2.Left += e.Location.X - MoveForms[form].X;
                form2.Top += e.Location.Y - MoveForms[form].Y;
            }
        }

        private static void Form_MouseDown1(object sender, MouseEventArgs e)
        {
            var form = ((Control)sender).FindForm();

            //判断是否为鼠标左键
            if (e.Button == MouseButtons.Left)
            {
                MoveForms[form] = new Point(e.Location.X, e.Location.Y);
            }
        }

        #endregion 支持拖动

        #region 为无边框窗体增加改变大小功能

        private static Dictionary<Control, ChangeSizeForForm> ChangeSizeFormData = new Dictionary<Control, ChangeSizeForForm>();

        /// <summary>
        /// 推荐使用AddAutoScale方法，一样可以是实现，功能更强大，效果更好
        /// 为窗体增加改变大小的功能
        /// </summary>
        /// <param name="form"></param>
        public static void AddChangeSizeForForm(this Form form)
        {
            if (!ChangeSizeFormData.ContainsKey(form))
            {
                ChangeSizeFormData.Add(form, new ChangeSizeForForm());
            }
            form.MouseDown += Form_MouseDown;
            form.MouseUp += Form_MouseUp;
            form.MouseMove += Form_MouseMove;
        }

        private static void Form_MouseDown(object sender, MouseEventArgs e)
        {
            ChangeSizeFormData[(Form)sender].isMouseDown = true;
        }

        private static void Form_MouseMove(object sender, MouseEventArgs e)
        {
            //鼠标移动过程中，坐标时刻在改变
            //当鼠标移动时横坐标距离窗体右边缘5像素以内且纵坐标距离下边缘也在5像素以内时，要将光标变为倾斜的箭头形状，同时拖拽方向direction置为MouseDirection.Declining
            if (e.Location.X >= ((Form)sender).Width - 5 && e.Location.Y > ((Form)sender).Height - 5)
            {
                ((Form)sender).Cursor = Cursors.SizeNWSE;
                ChangeSizeFormData[(Form)sender].direction = MouseDirection.Declining;
                // ChangeSizeFormData[(Form)sender].direction = MouseDirection.Declining;
            }
            //当鼠标移动时横坐标距离窗体右边缘5像素以内时，要将光标变为倾斜的箭头形状，同时拖拽方向direction置为MouseDirection.Herizontal
            else if (e.Location.X >= ((Form)sender).Width - 5)
            {
                ((Form)sender).Cursor = Cursors.SizeWE;
                ChangeSizeFormData[(Form)sender].direction = MouseDirection.Herizontal;
            }
            //同理当鼠标移动时纵坐标距离窗体下边缘5像素以内时，要将光标变为倾斜的箭头形状，同时拖拽方向direction置为MouseDirection.Vertical
            else if (e.Location.Y >= ((Form)sender).Height - 5)
            {
                ((Form)sender).Cursor = Cursors.SizeNS;
                ChangeSizeFormData[(Form)sender].direction = MouseDirection.Vertical;
            }
            //否则，以外的窗体区域，鼠标星座均为单向箭头（默认）
            else
            {
                ChangeSizeFormData[(Form)sender].direction = MouseDirection.None;
                ((Form)sender).Cursor = Cursors.Arrow;
            }
            //设定好方向后，调用下面方法，改变窗体大小
            ResizeWindow(sender);
        }

        private static void Form_MouseUp(object sender, MouseEventArgs e)
        {
            // 鼠标弹起，
            ChangeSizeFormData[(Form)sender].isMouseDown = false;
            ChangeSizeFormData[(Form)sender].direction = MouseDirection.None;
            //既然鼠标弹起了，那么就不能再改变窗体尺寸，拖拽方向置 none
        }

        private static void ResizeWindow(object sender)
        {
            ChangeSizeForForm changeSizeForForm = ChangeSizeFormData[(Form)sender];
            var direction = changeSizeForForm.direction;
            var isMouseDown = changeSizeForForm.isMouseDown;
            //这个判断很重要，只有在鼠标按下时才能拖拽改变窗体大小，如果不作判断，那么鼠标弹起和按下时，窗体都可以改变
            if (!isMouseDown)
                return;
            //MousePosition的参考点是屏幕的左上角，表示鼠标当前相对于屏幕左上角的坐标this.left和this.top的参考点也是屏幕，属性MousePosition是该程序的重点
            if (direction == MouseDirection.Declining)
            {
                //此行代码在mousemove事件中已经写过，在此再写一遍，并不多余，一定要写
                ((Form)sender).Cursor = Cursors.SizeNWSE;
                //下面是改变窗体宽和高的代码，不明白的可以仔细思考一下
                ((Form)sender).Width = Control.MousePosition.X - ((Form)sender).Left;
                ((Form)sender).Height = Control.MousePosition.Y - ((Form)sender).Top;
            }
            //以下同理
            if (direction == MouseDirection.Herizontal)
            {
                ((Form)sender).Cursor = Cursors.SizeWE;
                ((Form)sender).Width = Control.MousePosition.X - ((Form)sender).Left;
            }
            else if (direction == MouseDirection.Vertical)
            {
                ((Form)sender).Cursor = Cursors.SizeNS;
                ((Form)sender).Height = Control.MousePosition.Y - ((Form)sender).Top;
            }
            //即使鼠标按下，但是不在窗口右和下边缘，那么也不能改变窗口大小
            else
                ((Form)sender).Cursor = Cursors.Arrow;
        }

        /// <summary>
        ///
        /// </summary>
        public class ChangeSizeForForm
        {
            #region Fields

            public MouseDirection direction = MouseDirection.None;
            public bool isMouseDown = false;

            #endregion Fields
        }

        #endregion 为无边框窗体增加改变大小功能

        #region 为窗体增加圆角

        /// <summary>
        /// 设置窗体的圆角矩形
        /// </summary>
        /// <param name="form">需要设置的窗体</param>
        /// <param name="xRadius">圆角矩形的半径:X轴</param>
        /// <param name="yRadius">圆角矩形的半径：Y轴</param>
        public static void AddRound(this Form form, int xRadius, int yRadius)
        {
            var hRgn = Win32.CreateRoundRectRgn(0, 0, form.Width, form.Height, xRadius, yRadius);
            Win32.SetWindowRgn(form.Handle, hRgn, true);
            Win32.DeleteObject(hRgn);
        }

        #endregion 为窗体增加圆角

        #region Methods

        /// <summary>
        /// 倒影变换
        /// </summary>
        /// <param name="bmp">原图片</param>
        /// <param name="reflectionTop">倒影边距</param>
        /// <param name="reflectionBrightness">明亮度</param>
        /// <param name="reflectionTransparentStart">倒影开始透明度</param>
        /// <param name="reflectionTransparentEnd">倒影结束透明度</param>
        /// <param name="reflectionHeight">倒影高度</param>
        /// <returns></returns>
        public static Bitmap _倒影变换(Bitmap bmp, int reflectionTop = 10, int reflectionBrightness = -50, int reflectionTransparentStart = 200, int reflectionTransparentEnd = -0, int reflectionHeight = 50)
        {
            /// <summary>
            /// 图片最终高度
            /// </summary>
            int finallyHeight = bmp.Height + reflectionTop + reflectionHeight;

            Color pixel;
            int transparentGradient = 0;//透明梯度
            transparentGradient = (reflectionTransparentEnd - reflectionTransparentStart) / reflectionHeight;
            if (transparentGradient == 0)
                transparentGradient = 1;

            Bitmap result = new Bitmap(bmp.Width, finallyHeight);
            Graphics graphic = Graphics.FromImage(result);
            graphic.DrawImage(bmp, new RectangleF(0, 0, bmp.Width, bmp.Height));
            graphic.Dispose();

            for (int y = 0; y < reflectionHeight; y++)
            {
                for (int x = 0; x < bmp.Width; x++)
                {
                    pixel = bmp.GetPixel(x, bmp.Height - 1 - y);
                    int a = _检查RGB值ed有效范围(reflectionTransparentStart + y * transparentGradient);
                    if (pixel.A == 0 || pixel.A < a)
                    {
                        result.SetPixel(x, bmp.Height - 1 + reflectionTop + y, pixel);
                    }
                    else
                    {
                        int r = _检查RGB值ed有效范围(pixel.R + reflectionBrightness);
                        int g = _检查RGB值ed有效范围(pixel.G + reflectionBrightness);
                        int b = _检查RGB值ed有效范围(pixel.B + reflectionBrightness);
                        result.SetPixel(x, bmp.Height - 1 + reflectionTop + y, Color.FromArgb(a, r, g, b));
                    }
                }
            }
            return result;
        }

        /// <summary>
        /// 根据画笔大小计算出真是rectf
        /// </summary>
        /// <param name="rectf">要转换的rectf</param>
        /// <param name="pen">画笔大小大小</param>
        /// <returns></returns>
        public static RectangleF _根据画笔大小计算出真是rectf(RectangleF rectf, float pen)
        {
            RectangleF result = new RectangleF();
            result.Width = rectf.Width - (pen < 1 ? 0 : pen);
            result.Height = rectf.Height - (pen < 1 ? 0 : pen);
            result.X = rectf.X + (pen / 2f);
            result.Y = rectf.Y + (pen / 2f);
            return result;
        }

        /// <summary>
        /// 根据画笔大小转换rectf
        /// </summary>
        /// <param name="rectf">要转换的rectf</param>
        /// <param name="pen">画笔大小大小</param>
        /// <returns></returns>
        public static RectangleF _根据画笔大小转换rectf(RectangleF rectf, float pen)
        {
            RectangleF result = new RectangleF();
            result.Width = rectf.Width - (pen < 1 ? 0 : pen);
            result.Height = rectf.Height - (pen < 1 ? 0 : pen);
            result.X = rectf.X + (float)(pen / 2);
            result.Y = rectf.Y + (float)(pen / 2);
            return result;
        }

        /// <summary>
        /// 计算指定角度的坐标
        /// </summary>
        /// <param name="center">圆心坐标</param>
        /// <param name="radius">圆半径</param>
        /// <param name="angle">角度</param>
        /// <returns></returns>
        public static PointF _计算指定角度的坐标(PointF center, float radius, float angle)
        {
            if (radius == 0)
                return center;

            float w = 0;
            float h = 0;
            if (angle <= 90)
            {
                w = radius * (float)Math.Cos(Math.PI / 180 * angle);
                h = radius * (float)Math.Sin(Math.PI / 180 * angle);
            }
            else if (angle <= 180)
            {
                w = -radius * (float)Math.Sin(Math.PI / 180 * (angle - 90));
                h = radius * (float)Math.Cos(Math.PI / 180 * (angle - 90));
            }
            else if (angle <= 270)
            {
                w = -radius * (float)Math.Cos(Math.PI / 180 * (angle - 180));
                h = -radius * (float)Math.Sin(Math.PI / 180 * (angle - 180));
            }
            else
            {
                w = radius * (float)Math.Sin(Math.PI / 180 * (angle - 270));
                h = -radius * (float)Math.Cos(Math.PI / 180 * (angle - 270));
            }
            return new PointF(center.X + w, center.Y + h);
        }

        /// <summary>
        /// 检查RGB值ed有效范围
        /// </summary>
        /// <param name="rgb"></param>
        /// <returns></returns>
        public static int _检查RGB值ed有效范围(int rgb)
        {
            if (rgb < 0)
                return 0;
            if (rgb > 255)
                return 255;
            return rgb;
        }

        /// <summary>
        /// 结构转指针
        /// </summary>
        /// <typeparam name="T">结构类型</typeparam>
        /// <param name="info"></param>
        /// <returns></returns>
        public static IntPtr _结构转指针<T>(T info)
        {
            int size = Marshal.SizeOf(info);
            IntPtr intPtr = Marshal.AllocHGlobal(size);
            Marshal.StructureToPtr(info, intPtr, true);
            return intPtr;
        }

        /// <summary>
        /// 指针转结构
        /// </summary>
        /// <typeparam name="T">结构类型</typeparam>
        /// <param name="info"></param>
        /// <returns></returns>
        public static T _指针转结构<T>(IntPtr info)
        {
            return (T)Marshal.PtrToStructure(info, typeof(T));
        }

        ///////////////////////////////////////////////////////
        /// <summary>
        /// 转换成圆角
        /// </summary>
        /// <param name="rectf">要转换的rectf</param>
        /// <param name="radius">圆角半径的大小</param>
        /// <returns></returns>
        public static GraphicsPath _转换成圆角(RectangleF rectf, float radius = 0)
        {
            return _转换成圆角(rectf, radius, radius, radius, radius);
        }

        /// <summary>
        /// 转换成圆角
        /// </summary>
        /// <param name="rectf">要转换的rectf</param>
        /// <param name="leftTopRadius">左上角</param>
        /// <param name="rightTopRadius">右上角</param>
        /// <param name="rightBottomRadius">右下角</param>
        /// <param name="leftBottomRadius">左下角</param>
        /// <returns></returns>
        public static GraphicsPath _转换成圆角(RectangleF rectf, float leftTopRadius = 0f, float rightTopRadius = 0f, float rightBottomRadius = 0f, float leftBottomRadius = 0f)
        {
            GraphicsPath gp = new GraphicsPath();
            if (leftTopRadius > 0)
            {
                RectangleF lefttop_rect = new RectangleF(rectf.X, rectf.Y, leftTopRadius * 2, leftTopRadius * 2);
                gp.AddArc(lefttop_rect, 180, 90);
            }
            else
            {
                gp.AddLine(new PointF(rectf.X, rectf.Y), new PointF(rightTopRadius > 0 ? rectf.Right - rightTopRadius * 2 : rectf.Right, rectf.Y));
            }
            if (rightTopRadius > 0)
            {
                RectangleF righttop_rect = new RectangleF(rectf.Right - rightTopRadius * 2, rectf.Y, rightTopRadius * 2, rightTopRadius * 2);
                gp.AddArc(righttop_rect, 270, 90);
            }
            else
            {
                gp.AddLine(new PointF(rectf.Right, rectf.Y), new PointF(rectf.Right, rightBottomRadius > 0 ? rectf.Bottom - rightTopRadius * 2 : rectf.Bottom));
            }
            if (rightBottomRadius > 0)
            {
                RectangleF rightbottom_rect = new RectangleF(rectf.Right - rightTopRadius * 2, rectf.Bottom - rightTopRadius * 2, rightBottomRadius * 2, rightBottomRadius * 2);
                gp.AddArc(rightbottom_rect, 0, 90);
            }
            else
            {
                gp.AddLine(new PointF(rectf.Right, rectf.Bottom), new PointF(leftBottomRadius > 0 ? leftBottomRadius * 2 : rectf.X, rectf.Bottom));
            }
            if (leftBottomRadius > 0)
            {
                RectangleF rightbottom_rect = new RectangleF(rectf.X, rectf.Bottom - leftBottomRadius * 2, leftBottomRadius * 2, leftBottomRadius * 2);
                gp.AddArc(rightbottom_rect, 90, 90);
            }
            else
            {
                gp.AddLine(new PointF(rectf.X, rectf.Bottom), new PointF(rectf.X, leftTopRadius > 0 ? rectf.X + leftTopRadius * 2 : rectf.X));
            }
            gp.CloseAllFigures();
            return gp;
        }

        /// <summary>
        /// Adds the array data.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="array">The array.</param>
        /// <param name="data">The data.</param>
        /// <param name="max">The maximum.</param>
        public static void AddArrayData<T>(ref T[] array, T[] data, int max)
        {
            if (data == null || data.Length == 0)
            {
                return;
            }
            if (array.Length == max)
            {
                Array.Copy(array, data.Length, array, 0, array.Length - data.Length);
                Array.Copy(data, 0, array, array.Length - data.Length, data.Length);
            }
            else if (array.Length + data.Length > max)
            {
                T[] array2 = new T[max];
                for (int i = 0; i < max - data.Length; i++)
                {
                    array2[i] = array[i + (array.Length - max + data.Length)];
                }
                for (int j = 0; j < data.Length; j++)
                {
                    array2[array2.Length - data.Length + j] = data[j];
                }
                array = array2;
            }
            else
            {
                T[] array3 = new T[array.Length + data.Length];
                for (int k = 0; k < array.Length; k++)
                {
                    array3[k] = array[k];
                }
                for (int l = 0; l < data.Length; l++)
                {
                    array3[array3.Length - data.Length + l] = data[l];
                }
                array = array3;
            }
        }

        /// <summary>
        /// Calculates the maximum section from.
        /// </summary>
        /// <param name="values">The values.</param>
        /// <returns>System.Int32.</returns>
        public static double CalculateMaxSectionFrom(double[] values)
        {
            double num = values.Max();
            return CalculateMaxSection(num);
        }

        public static double CalculateMaxSectionFrom(double[][] values)
        {
            double num = values.Max(p => p.Max());
            return CalculateMaxSection(num);
        }

        /// <summary>
        /// Converts the size.
        /// </summary>
        /// <param name="size">The size.</param>
        /// <param name="angle">The angle.</param>
        /// <returns>SizeF.</returns>
        public static SizeF ConvertSize(SizeF size, float angle)
        {
            System.Drawing.Drawing2D.Matrix matrix = new System.Drawing.Drawing2D.Matrix();
            matrix.Rotate(angle);
            PointF[] array = new PointF[4];
            array[0].X = (0f - size.Width) / 2f;
            array[0].Y = (0f - size.Height) / 2f;
            array[1].X = (0f - size.Width) / 2f;
            array[1].Y = size.Height / 2f;
            array[2].X = size.Width / 2f;
            array[2].Y = size.Height / 2f;
            array[3].X = size.Width / 2f;
            array[3].Y = (0f - size.Height) / 2f;
            matrix.TransformPoints(array);
            float num = float.MaxValue;
            float num2 = float.MinValue;
            float num3 = float.MaxValue;
            float num4 = float.MinValue;
            PointF[] array2 = array;
            for (int i = 0; i < array2.Length; i++)
            {
                PointF pointF = array2[i];
                if (pointF.X < num)
                {
                    num = pointF.X;
                }
                if (pointF.X > num2)
                {
                    num2 = pointF.X;
                }
                if (pointF.Y < num3)
                {
                    num3 = pointF.Y;
                }
                if (pointF.Y > num4)
                {
                    num4 = pointF.Y;
                }
            }
            return new SizeF(num2 - num, num4 - num3);
        }

        /// <summary>
        /// Gets the color light.
        /// </summary>
        /// <param name="color">The color.</param>
        /// <returns>System.Drawing.Color.</returns>
        public static System.Drawing.Color GetColorLight(System.Drawing.Color color)
        {
            return System.Drawing.Color.FromArgb(color.R + (255 - color.R) * 40 / 100, color.G + (255 - color.G) * 40 / 100, color.B + (255 - color.B) * 40 / 100);
        }

        /// <summary>
        /// Gets the color light five.
        /// </summary>
        /// <param name="color">The color.</param>
        /// <returns>System.Drawing.Color.</returns>
        public static System.Drawing.Color GetColorLightFive(System.Drawing.Color color)
        {
            return System.Drawing.Color.FromArgb(color.R + (255 - color.R) * 50 / 100, color.G + (255 - color.G) * 50 / 100, color.B + (255 - color.B) * 50 / 100);
        }

        /// <summary>
        /// Gets the points from.
        /// </summary>
        /// <param name="points">The points.</param>
        /// <param name="soureWidth">Width of the soure.</param>
        /// <param name="sourceHeight">Height of the source.</param>
        /// <param name="width">The width.</param>
        /// <param name="height">The height.</param>
        /// <param name="dx">The dx.</param>
        /// <param name="dy">The dy.</param>
        /// <returns>PointF[].</returns>
        public static PointF[] GetPointsFrom(string points, float soureWidth, float sourceHeight, float width, float height, float dx = 0f, float dy = 0f)
        {
            string[] array = points.Split(new char[1]
            {
                ' '
            }, StringSplitOptions.RemoveEmptyEntries);
            PointF[] array2 = new PointF[array.Length];
            for (int i = 0; i < array.Length; i++)
            {
                int num = array[i].IndexOf(',');
                float num2 = Convert.ToSingle(array[i].Substring(0, num));
                float num3 = Convert.ToSingle(array[i].Substring(num + 1));
                array2[i] = new PointF(width * (num2 + dx) / soureWidth, height * (num3 + dy) / sourceHeight);
            }
            return array2;
        }

        /// <summary>
        /// 相对于屏幕显示的位置
        /// </summary>
        /// <param name="screen">窗体需要显示的屏幕</param>
        /// <param name="left">left</param>
        /// <param name="top">top</param>
        /// <returns></returns>
        public static Point GetScreenLocation(Screen screen, int left, int top)
        {
            return new Point(screen.Bounds.Left + left, screen.Bounds.Top + top);
        }

        public static bool IsDesignMode()
        {
            bool returnFlag = false;

            if (LicenseManager.UsageMode == LicenseUsageMode.Designtime)
            {
                returnFlag = true;
            }
            else if (Process.GetCurrentProcess().ProcessName == "devenv")
            {
                returnFlag = true;
            }

            return returnFlag;
        }

        /// <summary>
        ///为控件设置双缓冲
        /// </summary>
        /// <param name="ctr"></param>
        public static void SetDoubleBuffered(this Control ctr)
        {
            ctr.GetType().GetProperty("DoubleBuffered", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(ctr, true, null);
        }

        /// <summary>
        /// 为控件的datasourse设定为指定枚举,返回选择的枚举(),结构体的时候返回null
        /// </summary>
        /// <typeparam name="T">必须是枚举类型活着结构体类型</typeparam>
        /// <param name="ctr">必须是ListControl类型</param>
        /// <returns></returns>
        public static T ToEnum<T>(this ListControl ctr)
        {
            var type = typeof(T);
            var isStruct = !type.IsPrimitive && !type.IsEnum && type.IsValueType;//true表示结构体
            if (ctr.DataSource == null)
            {
                if (isStruct)
                {
                    ctr.DataSource = type.GetProperties().Select(s => s.Name).ToList();
                }
                else
                {
                    ctr.DataSource = Enum.GetValues(typeof(T));
                }
            }
            T res;
            if (ctr.SelectedValue != null)
            {
                var str = ctr.SelectedValue.ToString();

                if (isStruct)
                {
                    var trres = type.GetProperty(str);
                    return default(T);
                }
                else
                {
                    res = (T)Enum.Parse(typeof(T), str);
                }
            }
            else
            {
                res = default(T);
            }
            return res;
        }

        #endregion Methods

        #region MyRegion

        /// <summary>
        /// 获取控件的轮廓矩形,因为系统Bounds获取的矩形有bug;
        /// </summary>
        /// <param name="ctr"></param>
        /// <returns></returns>
        public static Rectangle GetRec(this Control ctr)
        {
            var rec = ctr.Bounds;
            rec.Offset(-1, -1);
            rec.Width += 1;
            rec.Height += 1;
            return rec;
        }

        #endregion MyRegion

        #region 获取图片的边界点

        /// <summary>
        /// 获取一个图片的边界点
        /// </summary>
        /// <param name="bitmap">图片</param>
        /// <param name="背景色">背景色</param>
        /// <param name="alpha">透明值:大于这个透明度的颜色点直接加入集合中</param>
        /// <param name="相似度">推荐10  越大,越严格,获得的点越小</param>
        /// <returns></returns>
        public static List<PointF> GetBorderPoints(Bitmap bitmap, Color 背景色, int alpha, int 相似度 = 10)
        {
            float diameter直径 = (float)Math.Sqrt(bitmap.Width * bitmap.Width + bitmap.Height * bitmap.Height);
            int intSplit整数分割 = 0;
            intSplit整数分割 = (int)(7 - (diameter直径 - 200) / 100);
            if (intSplit整数分割 < 1)
                intSplit整数分割 = 1;
            List<PointF> lstPoint = new List<PointF>();
            for (int i = 0; i < 360; i += intSplit整数分割)
            {
                for (int j = (int)diameter直径 / 2; j > 5; j--)
                {
                    Point p = CtrolTools.GetPointByAngle角度(i, j, new PointF(bitmap.Width / 2, bitmap.Height / 2));
                    if (p.X < 0 || p.Y < 0 || p.X >= bitmap.Width || p.Y >= bitmap.Height)
                        continue;
                    Color _color = bitmap.GetPixel(p.X, p.Y);
                    //如果当前点的颜色的透明度>alpha则将这个点加入集合;如果这个点和背景色不相似这加入集合
                    if (!(((int)_color.A) <= alpha || CtrolTools.IsLikeColor颜色是否相似(_color, 背景色, 相似度)))
                    {
                        if (!lstPoint.Contains(p))
                        {
                            lstPoint.Add(p);
                        }
                        break;
                    }
                }
            }
            return lstPoint;
        }

        /// <summary>
        /// 返回指定图片中的非透明区域
        /// </summary>
        /// <param name="bitmap"></param>
        /// <param name="colorTransparent"></param>
        /// <returns></returns>
        public static GraphicsPath GetGraphicsPathByImage(Bitmap bitmap, Color? colorTransparent = null)
        {
            //为位图计算创建图形路径
            //创建 GraphicsPath
            GraphicsPath graphicsPath = new GraphicsPath();
            //使用左上角的像素作为我们的透明色
            //使用左上角的一点的颜色作为我们透明色
            Color 透明色 = bitmap.GetPixel(0, 0);
            if (colorTransparent != null && colorTransparent != Color.Transparent && colorTransparent != Color.Empty)
                透明色 = colorTransparent.Value;
            //这是将列值存储在第一次发现不透明像素的位置。
            //该值将决定从何处开始扫描尾部不透明像素。
            //第一个找到点的X
            int colOpaquePixel = 0;
            // Go through all rows (Y axis)
            // 偏历所有行（Y方向）
            for (int row = 0; row < bitmap.Height; row++)
            {
                // Reset value
                //重设
                colOpaquePixel = 0;
                // Go through all columns (X axis)
                //偏历所有列（X方向）
                for (int col = 0; col < bitmap.Width; col++)
                {
                    // If this is an opaque pixel, mark it and search for anymore trailing behind
                    //如果是不需要透明处理的点则标记，然后继续偏历
                    if (bitmap.GetPixel(col, row) != 透明色)
                    {
                        // Opaque pixel found, mark current position
                        //记录当前
                        colOpaquePixel = col;
                        // Create another variable to set the current pixel position
                        //建立新变量来记录当前点
                        int colNext = col;
                        // Starting from current found opaque pixel, search for anymore opaque pixels
                        // trailing behind, until a transparent   pixel is found or minimum width is reached
                        ///从找到的不透明点开始，继续寻找不透明点,一直到找到或则达到图片宽度
                        for (colNext = colOpaquePixel; colNext < bitmap.Width; colNext++)
                            if (bitmap.GetPixel(colNext, row) == 透明色)
                                break;
                        // Form a rectangle for line of opaque   pixels found and add it to our graphics path
                        //将不透明点加到graphics path
                        graphicsPath.AddRectangle(new Rectangle(colOpaquePixel, row, colNext - colOpaquePixel, 1));
                        // No need to scan the line of opaque pixels just found
                        col = colNext;
                    }
                }
            }
            // Return calculated graphics path
            return graphicsPath;
        }

        #endregion 获取图片的边界点

        #region 颜色是否相似

        /// <summary>
        /// 颜色是否相似
        /// </summary>
        /// <param name="color1">颜色1</param>
        /// <param name="color2">颜色2</param>
        /// <param name="相似度">推荐10  越大,越严格,获得的点越小</param>
        /// <returns><c>true</c> if [is like color] [the specified color1]; otherwise, <c>false</c>.</returns>
        public static bool IsLikeColor颜色是否相似(Color color1, Color color2, int 相似度 = 10)
        {
            var cv = Math.Sqrt(Math.Pow((color1.R - color2.R), 2) + Math.Pow((color1.G - color2.G), 2) + Math.Pow((color1.B - color2.B), 2));
            if (cv <= 相似度)
                return true;
            else
                return false;
        }

        #endregion 颜色是否相似

        #region 根据角度得到坐标

        /// <summary>
        /// 功能描述:根据角度得到坐标
        /// </summary>
        /// <param name="angle角度"></param>
        /// <param name="radius半径"></param>
        /// <returns></returns>
        public static Point GetPointByAngle角度(float angle角度, float radius半径)
        {
            float y = (float)Math.Sin(Math.PI * (angle角度 / 180.00F)) * radius半径;
            float x = (float)Math.Cos(Math.PI * (angle角度 / 180.00F)) * radius半径;
            return new Point((int)x, (int)y);
        }

        /// <summary>
        /// 功能描述:根据角度得到坐标 加起点坐标
        /// </summary>
        /// <param name="angle角度">角度</param>
        /// <param name="radius半径">半径</param>
        /// <param name="起点">起点</param>
        /// <returns>返回值</returns>
        public static Point GetPointByAngle角度(float angle角度, float radius半径, PointF 起点)
        {
            float y = 起点.Y + (float)Math.Sin(Math.PI * (angle角度 / 180.00F)) * radius半径;
            float x = 起点.X + (float)Math.Cos(Math.PI * (angle角度 / 180.00F)) * radius半径;
            return new Point((int)x, (int)y);
        }

        #endregion 根据角度得到坐标

        #region 设定画布为高质量

        /// <summary>
        /// 设置GDI高质量模式抗锯齿
        /// </summary>
        /// <param name="g">The g.</param>
        public static void SetQuality(this Graphics g)
        {
            g.SmoothingMode = SmoothingMode.AntiAlias;  //使绘图质量最高，即消除锯齿
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;
            g.CompositingQuality = CompositingQuality.HighQuality;
        }

        #endregion 设定画布为高质量

        #region 设置控件Enabled，切不改变控件颜色

        /// <summary>
        /// 功能描述:设置控件Enabled，切不改变控件颜色
        /// 作　　者:HZH
        /// 创建日期:2019-03-04 13:43:32
        /// 任务编号:POS
        /// </summary>
        /// <param name="c">c</param>
        /// <param name="enabled">enabled</param>
        public static void SetControlEnabled(this Control c, bool enabled)
        {
            if (!c.IsDisposed)
            {
                if (enabled)
                {
                    CtrolTools.SetWindowLong(c.Handle, -16, -134217729 & CtrolTools.GetWindowLong(c.Handle, -16));
                }
                else
                {
                    CtrolTools.SetWindowLong(c.Handle, -16, 134217728 + CtrolTools.GetWindowLong(c.Handle, -16));
                }
            }
        }

        /// <summary>
        /// 功能描述:设置控件Enabled，切不改变控件颜色
        /// 作　　者:HZH
        /// 创建日期:2019-03-04 13:43:32
        /// 任务编号:POS
        /// </summary>
        /// <param name="cs">cs</param>
        /// <param name="enabled">enabled</param>
        public static void SetControlEnableds(Control[] cs, bool enabled)
        {
            for (int i = 0; i < cs.Length; i++)
            {
                Control c = cs[i];
                SetControlEnabled(c, enabled);
            }
        }

        #endregion 设置控件Enabled，切不改变控件颜色

        #region winAPI引用

        /// <summary>
        ///获取前景窗口。
        /// </summary>
        /// <returns>IntPtr.</returns>
        [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
        public static extern IntPtr GetForegroundWindow();

        /// <summary>
        /// 使窗口变长。
        /// </summary>
        /// <param name="hWnd">The h WND.</param>
        /// <param name="nIndex">Index of the n.</param>
        /// <returns>System.Int32.</returns>
        [DllImport("user32.dll ")]
        public static extern int GetWindowLong(IntPtr hWnd, int nIndex);

        /// <summary>
        /// 设置前景窗口。
        /// </summary>
        /// <param name="hWnd">The h WND.</param>
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
        [DllImport("user32.dll")]
        public static extern bool SetForegroundWindow(IntPtr hWnd);

        /// <summary>
        /// 设置窗口的长度。
        /// </summary>
        /// <param name="hWnd">The h WND.</param>
        /// <param name="nIndex">Index of the n.</param>
        /// <param name="wndproc">The wndproc.</param>
        /// <returns>System.Int32.</returns>
        [DllImport("user32.dll ")]
        public static extern int SetWindowLong(IntPtr hWnd, int nIndex, int wndproc);

        #endregion winAPI引用

        #region 文字绘制

        /// <summary>
        /// 带角度文字绘制 需要StringFormat point
        /// </summary>
        /// <param name="g"></param>
        /// <param name="s">要绘制的文本</param>
        /// <param name="font">字体</param>
        /// <param name="brush"></param>
        /// <param name="point"></param>
        /// <param name="format"></param>
        /// <param name="angle">角度</param>
        public static void DrawString(this Graphics g, string s, Font font, Brush brush, PointF point, float angle, StringFormat format)
        {
            using (Matrix transform = g.Transform)
            {
                using (Matrix transform2 = g.Transform)
                {
                    transform2.RotateAt(angle, point);
                    g.Transform = transform2;
                }
                g.DrawString(s, font, brush, point, format);
                g.Transform = transform;
            }
        }

        /// <summary>
        /// 带角度文字绘制 需要 point
        /// </summary>
        /// <param name="g"></param>
        /// <param name="s"></param>
        /// <param name="font"></param>
        /// <param name="brush"></param>
        /// <param name="point"></param>
        /// <param name="angle"></param>
        public static void DrawString(this Graphics g, string s, Font font, Brush brush, PointF point, float angle)
        {
            using (Matrix transform = g.Transform)
            {
                using (Matrix transform2 = g.Transform)
                {
                    transform2.RotateAt(angle, point);
                    g.Transform = transform2;
                }
                g.DrawString(s, font, brush, point);
                g.Transform = transform;
            }
        }

        /// <summary>
        /// 带角度文字绘制 需要 Rectangle
        /// </summary>
        /// <param name="g"></param>
        /// <param name="s"></param>
        /// <param name="font"></param>
        /// <param name="brush"></param>
        /// <param name="rec"></param>
        /// <param name="angle"></param>
        public static void DrawString(this Graphics g, string s, Font font, Brush brush, Rectangle rec, float angle)
        {
            using (Matrix transform = g.Transform)
            {
                using (Matrix transform2 = g.Transform)
                {
                    transform2.RotateAt(angle, new Point(rec.X, rec.Y));
                    g.Transform = transform2;
                }
                g.DrawString(s, font, brush, rec);
                g.Transform = transform;
            }
        }

        #endregion 文字绘制

        #region 根据控件宽度截取字符串

        /// <summary>
        /// 根据控件宽度截取字符串
        /// </summary>
        /// <param name="strSource"></param>
        /// <param name="fltControlWidth"></param>
        /// <param name="g"></param>
        /// <param name="font"></param>
        /// <returns></returns>
        public static string GetSubString(string strSource, float fltControlWidth, Graphics g, Font font)
        {
            try
            {
                fltControlWidth = fltControlWidth - 20;
                strSource = strSource.Trim();
                while (true)
                {
                    System.Drawing.SizeF sizeF = g.MeasureString(strSource.Replace(" ", "A"), font);
                    if (sizeF.Width > fltControlWidth)
                    {
                        strSource = strSource.TrimEnd('…');
                        if (strSource.Length <= 1)
                            return "";
                        strSource = strSource.Substring(0, strSource.Length - 1).Trim() + "…";
                    }
                    else
                    {
                        return strSource;
                    }
                }
            }
            finally
            {
                g.Dispose();
            }
        }

        #endregion 根据控件宽度截取字符串

        #region 获取字符串宽度

        /// <summary>
        /// 获取字符串宽度
        /// </summary>
        /// <param name="strSource"></param>
        /// <param name="g"></param>
        /// <param name="font"></param>
        /// <returns></returns>
        public static int GetStringWidth(
           string strSource,
           System.Drawing.Graphics g,
           System.Drawing.Font font)
        {
            string[] strs = strSource.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
            float fltWidth = 0;
            foreach (var item in strs)
            {
                System.Drawing.SizeF sizeF = g.MeasureString(strSource.Replace(" ", "A"), font);
                if (sizeF.Width > fltWidth)
                    fltWidth = sizeF.Width;
            }

            return (int)fltWidth;
        }

        #endregion 获取字符串宽度

        #region 动画特效

        //隐藏窗口，缺省则显示窗口
        /// <summary>
        /// The aw activate
        /// </summary>
        public const Int32 AW_ACTIVATE = 0x00020000;

        //使用滑动类型。缺省则为滚动动画类型。当使用AW_CENTER标志时，这个标志就被忽略
        /// <summary>
        /// The aw blend
        /// </summary>
        public const Int32 AW_BLEND = 0x00080000;

        //从下到上显示
        /// <summary>
        /// The aw center
        /// </summary>
        public const Int32 AW_CENTER = 0x00000010;

        //若使用了AW_HIDE标志，则使窗口向内重叠，即收缩窗口；否则使窗口向外扩展，即展开窗口
        /// <summary>
        /// The aw hide
        /// </summary>
        public const Int32 AW_HIDE = 0x00010000;

        //从左到右显示
        /// <summary>
        /// The aw hor negative
        /// </summary>
        public const Int32 AW_HOR_NEGATIVE = 0x00000002;

        //dwflag的取值如下
        /// <summary>
        /// The aw hor positive
        /// </summary>
        public const Int32 AW_HOR_POSITIVE = 0x00000001;

        //激活窗口。在使用了AW_HIDE标志后不能使用这个标志
        /// <summary>
        /// The aw slide
        /// </summary>
        public const Int32 AW_SLIDE = 0x00040000;

        //从上到下显示
        /// <summary>
        /// The aw ver negative
        /// </summary>
        public const Int32 AW_VER_NEGATIVE = 0x00000008;

        //从右到左显示
        /// <summary>
        /// The aw ver positive
        /// </summary>
        public const Int32 AW_VER_POSITIVE = 0x00000004;

        /// <summary>
        /// 设置窗口的动画
        /// </summary>
        /// <param name="whnd">The WHND.</param>
        /// <param name="dwtime">The dwtime.</param>
        /// <param name="dwflag">The dwflag.</param>
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
        [DllImport("user32.dll")]
        public static extern bool AnimateWindow(IntPtr whnd, int dwtime, int dwflag);

        //透明度从高到低

        #endregion 动画特效

        #region 冻结控件

        /// <summary>
        /// The m LST freeze control
        /// </summary>
        private static Dictionary<Control, bool> m_lstFreezeControl = new Dictionary<Control, bool>();

        /// <summary>
        /// Handles the Disposed event of the control control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
        private static void control_Disposed(object sender, EventArgs e)
        {
            try
            {
                if (m_lstFreezeControl.ContainsKey((Control)sender))
                    m_lstFreezeControl.Remove((Control)sender);
            }
            catch { }
        }

        #endregion 冻结控件

        #region 几何方法

        public static RectangleF InflateEx(this RectangleF rec, int x, int y)
        {
            rec.Width -= x;
            rec.Height -= y;
            return rec;
        }

        public static Rectangle InflateEx(this Rectangle rec, int x, int y)
        {
            rec.Width -= x;
            rec.Height -= y;
            return rec;
        }

        /// <summary>
        ///计算绘制位置y。
        /// </summary>
        /// <param name="max">The maximum.</param>
        /// <param name="min">The minimum.</param>
        /// <param name="height">The height.</param>
        /// <param name="value">The value.</param>
        /// <returns>System.Single.</returns>
        public static float ComputePaintLocationY(int max, int min, int height, int value)
        {
            if ((float)(max - min) == 0f)
            {
                return height;
            }
            return (float)height - (float)(value - min) * 1f / (float)(max - min) * (float)height;
        }

        /// <summary>
        /// 计算绘制位置y。
        /// </summary>
        /// <param name="max">The maximum.</param>
        /// <param name="min">The minimum.</param>
        /// <param name="height">The height.</param>
        /// <param name="value">The value.</param>
        /// <returns>System.Single.</returns>
        public static float ComputePaintLocationY(float max, float min, float height, float value)
        {
            if (max - min == 0f)
            {
                return height;
            }
            return height - (value - min) / (max - min) * height;
        }

        /// <summary>
        /// 根据矩形和圆得到一个圆角矩形Path
        /// </summary>
        /// <param name="rect">矩形</param>
        /// <param name="圆角大小">圆角大小</param>
        /// <returns>GraphicsPath.绘图路径</returns>
        public static GraphicsPath GetGraphicsPathByRectangle(this Rectangle rect, int 圆角大小)
        {
            GraphicsPath 圆角矩形Path = new GraphicsPath();
            圆角矩形Path.AddArc(rect.X, rect.Y, 圆角大小 * 2, 圆角大小 * 2, 180, 90);
            圆角矩形Path.AddLine(rect.X + 圆角大小, rect.Y, rect.Right - 圆角大小 * 2, rect.Y);
            圆角矩形Path.AddArc(rect.X + rect.Width - 圆角大小 * 2, rect.Y, 圆角大小 * 2, 圆角大小 * 2, 270, 90);
            圆角矩形Path.AddLine(rect.Right, rect.Y + 圆角大小 * 2, rect.Right, rect.Y + rect.Height - 圆角大小 * 2);
            圆角矩形Path.AddArc(rect.X + rect.Width - 圆角大小 * 2, rect.Y + rect.Height - 圆角大小 * 2, 圆角大小 * 2, 圆角大小 * 2, 0, 90);
            圆角矩形Path.AddLine(rect.Right - 圆角大小 * 2, rect.Bottom, rect.X + 圆角大小 * 2, rect.Bottom);
            圆角矩形Path.AddArc(rect.X, rect.Bottom - 圆角大小 * 2, 圆角大小 * 2, 圆角大小 * 2, 90, 90);
            圆角矩形Path.AddLine(rect.X, rect.Bottom - 圆角大小 * 2, rect.X, rect.Y + 圆角大小 * 2);
            圆角矩形Path.CloseFigure();
            return 圆角矩形Path;
        }

        /// <summary>
        /// 从矩形中获取菱形.
        /// </summary>
        /// <param name="rect">The rect.</param>
        /// <returns>Point[].</returns>
        public static Point[] GetRhombusFromRectangle(Rectangle rect)
        {
            return new Point[5]
            {
                new Point(rect.X, rect.Y + rect.Height / 2),
                new Point(rect.X + rect.Width / 2, rect.Y + rect.Height - 1),
                new Point(rect.X + rect.Width - 1, rect.Y + rect.Height / 2),
                new Point(rect.X + rect.Width / 2, rect.Y),
                new Point(rect.X, rect.Y + rect.Height / 2)
            };
        }

        /// <summary>
        /// 绘制坐标分界。
        /// </summary>
        /// <param name="g">The g.</param>
        /// <param name="penLine">The pen line.</param>
        /// <param name="penDash">The pen dash.</param>
        /// <param name="font">The font.</param>
        /// <param name="brush">The brush.</param>
        /// <param name="sf">The sf.</param>
        /// <param name="degree">The degree.</param>
        /// <param name="max">The maximum.</param>
        /// <param name="min">The minimum.</param>
        /// <param name="width">The width.</param>
        /// <param name="height">The height.</param>
        /// <param name="left">The left.</param>
        /// <param name="right">The right.</param>
        /// <param name="up">Up.</param>
        /// <param name="down">Down.</param>
        public static void PaintCoordinateDivide(Graphics g, System.Drawing.Pen penLine, System.Drawing.Pen penDash, Font font, System.Drawing.Brush brush, StringFormat sf, int degree, int max, int min, int width, int height, int left = 60, int right = 8, int up = 8, int down = 8)
        {
            for (int i = 0; i <= degree; i++)
            {
                int value = (max - min) * i / degree + min;
                int num = (int)ComputePaintLocationY(max, min, height - up - down, value) + up + 1;
                g.DrawLine(penLine, left - 1, num, left - 4, num);
                if (i != 0)
                {
                    g.DrawLine(penDash, left, num, width - right, num);
                }
                g.DrawString(value.ToString(), font, brush, new Rectangle(-5, num - font.Height / 2, left, font.Height), sf);
            }
        }

        #endregion 几何方法

        #region 未知方法

        /// <summary>
        /// 关闭进程面板。
        /// </summary>
        /// <param name="parent">The parent.</param>
        public static void CloseProcessPanel(Control parent)
        {
            if (parent.InvokeRequired)
            {
                parent.BeginInvoke(new MethodInvoker(delegate
                {
                    CloseProcessPanel(parent);
                }));
            }
            else if (parent != null)
            {
                Control control = HaveProcessPanelControl(parent);
                if (control != null)
                {
                    Form frm = control.Tag as Form;
                    if (frm != null && !frm.IsDisposed && frm.Visible)
                    {
                        if (frm.InvokeRequired)
                        {
                            frm.BeginInvoke(new MethodInvoker(delegate
                            {
                                frm.Hide();
                            }));
                        }
                        else
                        {
                            frm.Hide();
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 有过程控制面板。
        /// </summary>
        /// <param name="parent">The parent.</param>
        /// <returns>Control.</returns>
        public static Control HaveProcessPanelControl(Control parent)
        {
            Control[] array = parent.Controls.Find("myprogressPanelext", false);
            Control result;
            if (array.Length > 0)
            {
                result = array[0];
            }
            else
            {
                result = null;
            }
            return result;
        }

        #endregion 未知方法

        private static double CalculateMaxSection(double num)
        {
            if (num <= 5)
            {
                return 5;
            }
            if (num <= 10)
            {
                return 10;
            }
            int digit = num.ToString().Length - 2;
            int num2 = int.Parse(num.ToString().Substring(0, 2));
            if (num2 < 12)
            {
                return 12 * GetPow(digit);
            }
            if (num2 < 14)
            {
                return 14 * GetPow(digit);
            }
            if (num2 < 16)
            {
                return 16 * GetPow(digit);
            }
            if (num2 < 18)
            {
                return 18 * GetPow(digit);
            }
            if (num2 < 20)
            {
                return 20 * GetPow(digit);
            }
            if (num2 < 22)
            {
                return 22 * GetPow(digit);
            }
            if (num2 < 24)
            {
                return 24 * GetPow(digit);
            }
            if (num2 < 26)
            {
                return 26 * GetPow(digit);
            }
            if (num2 < 28)
            {
                return 28 * GetPow(digit);
            }
            if (num2 < 30)
            {
                return 30 * GetPow(digit);
            }
            if (num2 < 40)
            {
                return 40 * GetPow(digit);
            }
            if (num2 < 50)
            {
                return 50 * GetPow(digit);
            }
            if (num2 < 60)
            {
                return 60 * GetPow(digit);
            }
            if (num2 < 80)
            {
                return 80 * GetPow(digit);
            }
            return 100 * GetPow(digit);
        }

        /// <summary>
        /// Gets the pow.
        /// </summary>
        /// <param name="digit">The digit.</param>
        /// <returns>System.Int32.</returns>
        private static int GetPow(int digit)
        {
            int num = 1;
            for (int i = 0; i < digit; i++)
            {
                num *= 10;
            }
            return num;
        }

        #region 滚动条    English:scroll bar

        private static uint SB_BOTH = 0x3;
        private static uint SB_CTL = 0x2;
        private static uint SB_HORZ = 0x0;
        private static uint SB_VERT = 0x1;

        public enum ScrollInfoMask : uint
        {
            SIF_RANGE = 0x1,
            SIF_PAGE = 0x2,
            SIF_POS = 0x4,
            SIF_DISABLENOSCROLL = 0x8,
            SIF_TRACKPOS = 0x10,
            SIF_ALL = (SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS),
            SB_THUMBTRACK = 5,
            WM_HSCROLL = 0x0114,
            WM_VSCROLL = 0x0115,
            SB_LINEUP = 0,
            SB_LINEDOWN = 1,
            SB_LINELEFT = 0,
            SB_LINERIGHT = 1,
        }

        /// <summary>
        ///获取水平滚动条信息
        /// </summary>
        /// <param name="hWnd">The h WND.</param>
        /// <returns>Scrollbarinfo.</returns>
        public static SCROLLINFO GetHScrollBarInfo(IntPtr hWnd)
        {
            SCROLLINFO info = new SCROLLINFO();
            info.cbSize = (int)Marshal.SizeOf(info);
            info.fMask = (int)ScrollInfoMask.SIF_DISABLENOSCROLL | (int)ScrollInfoMask.SIF_ALL;
            int intRef = GetScrollInfo(hWnd, SB_HORZ, ref info);
            return info;
        }

        /// <summary>
        /// 获取垂直滚动条信息
        /// </summary>
        /// <param name="hWnd">The h WND.</param>
        /// <returns>Scrollbarinfo.</returns>
        public static SCROLLINFO GetVScrollBarInfo(IntPtr hWnd)
        {
            SCROLLINFO info = new SCROLLINFO();
            info.cbSize = (int)Marshal.SizeOf(info);
            info.fMask = (int)ScrollInfoMask.SIF_DISABLENOSCROLL | (int)ScrollInfoMask.SIF_ALL;
            int intRef = GetScrollInfo(hWnd, SB_VERT, ref info);
            return info;
        }

        /// <summary>
        /// 控件向下滚动一个单位
        /// </summary>
        /// <param name="handle">控件句柄</param>
        public static void ScrollDown(IntPtr handle)
        {
            SendMessage(handle, (int)ScrollInfoMask.WM_VSCROLL, (int)ScrollInfoMask.SB_LINEDOWN, 0);
        }

        /// <summary>
        /// 控件向左滚动一个单位
        /// </summary>
        /// <param name="handle">控件句柄</param>
        public static void ScrollLeft(IntPtr handle)
        {
            SendMessage(handle, (int)ScrollInfoMask.WM_HSCROLL, (int)ScrollInfoMask.SB_LINELEFT, 0);
        }

        /// <summary>
        /// 控件向右滚动一个单位
        /// </summary>
        /// <param name="handle">控件句柄</param>
        public static void ScrollRight(IntPtr handle)
        {
            SendMessage(handle, (int)ScrollInfoMask.WM_VSCROLL, (int)ScrollInfoMask.SB_LINERIGHT, 0);
        }

        /// <summary>
        /// 控件向上滚动一个单位
        /// </summary>
        /// <param name="handle">控件句柄</param>
        public static void ScrollUp(IntPtr handle)
        {
            SendMessage(handle, (int)ScrollInfoMask.WM_VSCROLL, (int)ScrollInfoMask.SB_LINEUP, 0);
        }

        public static void SetHScrollValue(IntPtr handle, int value)
        {
            var info = GetHScrollBarInfo(handle);
            info.nPos = value;
            SetScrollInfo(handle, SB_HORZ, ref info, true);
            PostMessage(handle, (int)ScrollInfoMask.WM_HSCROLL, MakeLong((short)ScrollInfoMask.SB_THUMBTRACK, highPart: (short)info.nPos), 0);
        }

        public static void SetVScrollValue(IntPtr handle, int value)
        {
            var info = GetVScrollBarInfo(handle);
            info.nPos = value;
            SetScrollInfo(handle, SB_VERT, ref info, true);
            PostMessage(handle, (int)ScrollInfoMask.WM_VSCROLL, MakeLong((short)ScrollInfoMask.SB_THUMBTRACK, highPart: (short)info.nPos), 0);
        }

        /// <summary>
        /// ShowScrollBar
        /// </summary>
        /// <param name="hWnd">hWnd</param>
        /// <param name="wBar">0:horizontal,1:vertical,3:both</param>
        /// <param name="bShow">bShow</param>
        /// <returns></returns>
        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool ShowScrollBar(IntPtr hWnd, int wBar, bool bShow);

        [DllImport("user32.dll", SetLastError = true, EntryPoint = "GetScrollInfo")]
        private static extern int GetScrollInfo(IntPtr hWnd, uint fnBar, ref SCROLLINFO psbi);

        private static uint MakeLong(short lowPart, short highPart)
        {
            return (ushort)lowPart | (uint)(highPart << 16);
        }

        [DllImport("user32.dll", EntryPoint = "PostMessage")]
        private static extern bool PostMessage(IntPtr handle, int msg, uint wParam, uint lParam);

        [DllImport("User32.dll", EntryPoint = "SendMessage")]
        private static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);

        [DllImport("user32.dll")]//[return: MarshalAs(UnmanagedType.Bool)]
        private static extern int SetScrollInfo(IntPtr handle, uint fnBar, ref SCROLLINFO si, bool fRedraw);

        public struct SCROLLINFO
        {
            #region Fields

            public int cbSize;
            public int fMask;
            public int nMax;
            public int nMin;
            public int nPage;
            public int nPos;
            public int nTrackPos;

            #endregion Fields

            #region Properties

            public int ScrollMax { get { return nMax + 1 - nPage; } }

            #endregion Properties
        }

        #endregion 滚动条    English:scroll bar
    }

    #region 记录控件的大小和位置和字体

    /// <summary>
    /// 用于记录控件的大小和位置和字体;可以考虑用Struct结构体代替
    /// </summary>
    public class CtrolInfo
    {
        #region Properties

        public Font Font { get; set; }
        public Rectangle Rectangle { get; set; }

        #endregion Properties

        //= new Rectangle();
    }

    #endregion 记录控件的大小和位置和字体
}